/*
disp.cpp
Utility display functions for developing windows programmes.
copyright 2007 A. M. Steane
The disp() functions are basic display functions, showing messages in
the window set by the last call to disp(hwnd). They require
<windows.h> and either <stdio.h> or <cstdio>
An initial call to disp(hwnd) tells the display function which window to use.
*/
#include <windows.h>
//#include <stdio.h>
#include <cstdio>
HWND hdisp_window_global = (HWND) NULL;
void disp(HWND hwnd) // set up the window for the disp() functions
{ hdisp_window_global = hwnd; }
void disp(const char* s)
// display a message in the display window (hdisp_window_global), and scroll it
{
if (s) // if the string is not empty
{ if (hdisp_window_global) // if the window has been set up
{
// set up the font
HDC hdc = GetDC(hdisp_window_global);
SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));
// get the window rectangle
RECT rect;
GetClientRect(hdisp_window_global, &rect);
// choose the location: top right of the window
if (rect.bottom - rect.top > 400) rect.bottom = rect.top + 400;
if (rect.right - rect.left > 400) rect.left = rect.right - 400;
// get the character height and scroll this part of the window by one line
TEXTMETRIC tm;
GetTextMetrics(hdc, &tm) ;
int ch = tm.tmHeight;
ScrollWindow(hdisp_window_global, 0, -ch, &rect, &rect) ;
// if you want transparent text, uncomment the next line
// SetBkMode(hdc, TRANSPARENT);
// write out the text and tidy up
TextOut(hdc, rect.left+1, rect.bottom-2*ch, s, strlen(s)) ;
ReleaseDC(hdisp_window_global, hdc) ;
ValidateRect(hdisp_window_global, NULL) ;
}
else
MessageBox(NULL, s,"(disp was called with no window)", MB_OK);
}
}
void disp(const char* s, const int n1, const int n2, const int numpar)
/* display a string with either 1 or 2 integer parameters. The user does not
normally call this directly. Rather, it is used by the functions below. This
function takes care of avoiding overflow errors.
*/
{ // prepare the message string in sbuffer, then call disp
const int BUFSIZE = 200;
char sbuffer[BUFSIZE+1];
if ( strstr(s,"%d") && (strlen(s) < BUFSIZE-50) )
sprintf(sbuffer, s, n1, n2);
else // either user did not give %d, or we need to truncate a long message
{
char sutil[BUFSIZE-50];
strncpy(sutil,s,BUFSIZE-60);
if ( strlen(s) >= BUFSIZE-50 ) strcat(sutil,"...");
if ( numpar==1 ) strcat(sutil," %d");
else strcat(sutil," %d %d");
sprintf(sbuffer, sutil, n1, n2);
// we hope n1 and n2 will not occupy more than 46 characters
}
disp(sbuffer);
}
void disp(const char* s, const int n)
/* display a string and an integer
e.g. disp("number of widgets =", nw);
disp("%d widgets", nw);
*/
{ disp(s,n,0,1); }
void disp(const char* s, const int n1, const int n2)
/* display a string with two integer parameters
e.g. disp("%d widgets with %d knobs", nw, nk);
*/
{ disp(s,n1,n2,2); }
void disp(const char* s, const double x1, const double x2=0.0)
/* display a string with double parameters
(this is the same as integer case above, with the modification %d becomes %lg)
e.g. disp("ratio = ", r);
disp("ratio = %lg", r);
disp("x=%lg, sin(x)=%lg", x, sin(x));
*/
// same as above, but now for parameter type double
{
const int BUFSIZE = 200;
char sbuffer[BUFSIZE+1];
if ( strstr(s,"%lg") && (strlen(s) < BUFSIZE-50) )
sprintf(sbuffer, s, x1, x2);
else // either user did not give %lg, or we need to truncate a long message
{
char sutil[BUFSIZE-50];
strncpy(sutil,s,BUFSIZE-60);
if ( strlen(s) >= BUFSIZE-50 ) strcat(sutil,"...");
strcat(sutil," %lg %lg");
sprintf(sbuffer, sutil, x1, x2);
// we hope x1 and x2 will not occupy more than 50 characters
}
disp(sbuffer);
}
void disp(const char* s1, const char* s2)
// ditto, but for a pair of strings
{ if (hdisp_window_global)
{ char sbuffer[300];
if (strlen(s1)>150)
{ // truncate long messages
char strunc[150];
strncpy(strunc,s1,140);
strcat(strunc,"... %s");
sprintf(sbuffer, strunc, s2);
}
else sprintf(sbuffer, s1, s2);
//dispMsg(hwnd,s,n1,n2);
disp(sbuffer);
}
}